home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / s0ftpj / spf.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-12-17  |  4.9 KB  |  212 lines

  1.     /*     
  2.     **    vecna - vecna@s0ftpj.org
  3.     **    simple packet forwarder from datalink level
  4.     **    using libvsk - unique file "spf.c"
  5.     */
  6.  
  7. #include "libvsk.h"
  8. #include <errno.h>
  9.  
  10. extern int errno;
  11.  
  12. #define fatal(M)    {       \
  13.             perror(M); \
  14.             exit(0);   \
  15.             }
  16.  
  17. int check_dup(struct ipkt *);
  18. void setport(char *, char *, int[]); 
  19.  
  20. int main(int argc, char **argv)
  21.     {
  22.     int dlsfd, rsfd, opt, proto, forward, hdrincl =1, offset =0, x,
  23.     port[4]={0, 0xFFFF, 0, 0xFFFF};
  24.     /* 
  25.     **    datalink sockfd, raw sockfd, options index, proto 
  26.     **    listened, offset is size datalink protocol header 
  27.     **    port[4] array for puts source/dest/high/low port
  28.     */
  29.     char *iface;
  30.     /*     
  31.     **    interface name.
  32.     */
  33.     char *ipsrc, *ipdst;
  34.     /* 
  35.     **    ipsrc =fucked host, ipdst =bnc ip
  36.     */
  37.     unsigned int real;
  38.     /*
  39.     **    real ip of attacker where forward packets
  40.     */
  41.     char *rcvd =malloc(sizeof(struct ipkt));
  42.     /*
  43.     **    memory area where put packet, packet is readed with
  44.     **    datalink header, offset is size of this header and
  45.     **    is used on main cicle, *rcvd is delclared here for
  46.     **    make only one allocation.
  47.     */
  48.  
  49.     printf("\t simple packet forwarded for multiple pourpose\n");
  50.     printf("\t by vecna - vecna@s0ftpj.org - www.s0ftpj.org\n\n");
  51.  
  52.     if(argc != 11)
  53.         {
  54.         printf( "\t usage %s -t -n -p -i -s"
  55.             "\n\t -t source of packet"
  56.             "\n\t -n new destination"
  57.             "\n\t -s service (UDP/TCP) type (ICMP) 0 if any"
  58.             "\n\t -p protocol"
  59.             "\n\t -i interface"
  60.                 "\n",argv[0]);
  61.         exit(0);
  62.         }
  63.  
  64.     while(( opt = getopt(argc, argv, "t:n:i:p:s:")) != -1)
  65.         {
  66.         struct protoent *pe;    
  67.         switch(opt)
  68.             {
  69.             case 't':
  70.                 ipsrc =optarg;
  71.                 break;
  72.             case 'n':
  73.                 if(( real =inet_addr(optarg)) == -1)
  74.                     {
  75.                     errno =EINVAL;
  76.                     fatal("-r option required IP");
  77.                     }
  78.                 break;
  79.             case 'p':
  80.                 if ((pe = getprotobyname(optarg)) == NULL)
  81.                     fatal("getprotobyname");
  82.                 proto = pe->p_proto;
  83.                 break;
  84.             case 'i':
  85.                 iface =optarg;
  86.                 break;
  87.             case 's':
  88.                                 if(!atoi(optarg))
  89.                                         break;
  90.                 port[2] =port[3] =atoi(optarg);
  91.                 break;
  92.             default:
  93.                 if(optarg)
  94.                     fprintf(stderr,"%s on",optarg);
  95.                 errno =EINVAL;
  96.                 fatal(" getopt()");
  97.                 break;
  98.             }
  99.         }
  100.  
  101.     ipdst =NULL;
  102.  
  103.     if(( dlsfd =set_vsk_param(ipsrc, ipdst, port,
  104.                 iface, proto, IO_IN, IP_FW_INSERT, 0, 0))<0)
  105.          fatal("set_vsk: IP_FW_INSERT");
  106.  
  107.     /* 
  108.     **    IP_FW_DELETE must be used on signal(SIGCLOSE, unset_vsk()); 
  109.     **    or use "ipchains -F", as in this example where filtering 
  110.     **    rules is not clean after end of program.
  111.     */
  112.  
  113.     if((offset =get_offset(dlsfd, iface)) <0)
  114.         fatal("get device offset");
  115.  
  116.     if((forward = socket(AF_INET, SOCK_RAW, proto)) == -1)
  117.         fatal("forward socket - SOCK_RAW");
  118.  
  119.     if((x = setsockopt(forward, IPPROTO_IP, IP_HDRINCL, 
  120.                     &hdrincl, sizeof(hdrincl))) == -1)
  121.         fatal("setsockopt - IP_HDRINCL");
  122.  
  123.     while(1)
  124.         {
  125.         struct ipkt *packet;
  126.                 static int last_id;
  127.  
  128.         read(dlsfd, rcvd, sizeof(struct ipkt));
  129.  
  130.         (char *)packet = rcvd + offset; 
  131.  
  132.         if(check_dup(packet))
  133.             continue;
  134.  
  135. /*     questo e` il ciclo principale, in ordine:
  136. leggo sul socket a datalink quello che mi arriva, faccio un cast in una
  137. struttura ipkt che contiene ip header + buffer dati (in questo momento non
  138. conosco ancora il protocollo di livello inferiore) dopo aver sommato l'offset
  139. per levare l'header di livello 2, poi con check_dup controllo se e` il 
  140. pacchetto che ho appena ristrasmesso o se e` un altro pacchetto, poi con
  141. check_packet controllo se e` uno dei pacchetti filtrati, poi ... vediamo il
  142. codice ...     */ 
  143.  
  144.         if(check_packet(packet, packet->ip.protocol))
  145.             {
  146.             struct sockaddr_in sin;
  147.  
  148.             struct udphdr *udp;
  149.             struct tcphdr *tcp;
  150.             struct icmphdr *icmp;
  151.  
  152.     /** other manipulation on iphdr can applied here **/
  153.             packet->ip.daddr = real;
  154.             packet->ip.check = 0x00;
  155.  
  156. /*     bhe, e` abbastanza semplice, qui ho il pacchetto in una struttura 
  157. ipkt, a seconda del campo "protocol" riesco a fare degli opportuni cast e 
  158. lavorare anche su quell'header, dopo aver letto o cambiato o fatto qualunque
  159. cosa al pacchetto...    */
  160.  
  161.             switch(packet->ip.protocol)
  162.                 {
  163.                 case IPPROTO_ICMP:
  164.                     (char *)icmp =(char *)packet 
  165.                         +sizeof(struct iphdr);
  166.                     sin.sin_port =htons(0);
  167.                     break;                
  168.                 case IPPROTO_TCP:
  169.                     (char *)tcp =(char *)packet 
  170.                         +sizeof(struct iphdr);
  171.                     sin.sin_port =tcp->dest;
  172.                     break;
  173.                 case IPPROTO_UDP:
  174.                     (char *)udp =(char *)packet 
  175.                         +sizeof(struct iphdr);
  176.                     sin.sin_port =udp->dest;
  177.                     break;
  178.                 default:
  179.                     printf(" PROTOCOL NOT SUPP\n");
  180.                     break;
  181.     /* 
  182.     **    other manipulation at icmp/udp/tcp header 
  183.     **    can applied on switch() 
  184.     */
  185.                 }
  186.  
  187.             sin.sin_family = AF_INET;
  188.             sin.sin_addr.s_addr = packet->ip.daddr;
  189.  
  190.             x =resend(forward, packet, sin, 
  191.                     ntohs(packet->ip.tot_len), NULL, 0);
  192.             if(x < 0)
  193.                 fatal("sendto on forwarding packet");
  194.             }
  195.         }
  196.     free(rcvd);    
  197.     /* never used :) */
  198.     }
  199.  
  200. int check_dup(struct ipkt *packet)
  201.     {
  202.     static int last_id;
  203.     int id =htons(packet->ip.id);
  204.  
  205.     if(id ==htons(last_id))
  206.         return 1;
  207.  
  208.     last_id =packet->ip.id;
  209.  
  210.     return 0;
  211.     }
  212.